#ifndef _AVLTREE_H_
#define _AVLTREE_H_

#include <stdint.h>
#include <sys/types.h>
            
typedef int z_compare_func (const void* key1, const void *key2);
typedef void z_destroy_notify (void *data);
typedef void z_hfunc (void *key, void *value, void *userdata);

typedef struct z_tree z_tree;

/* Create a new avl tree
 * @param key_compare_func a function to compare two key
 * @return a new avl tree
 */
z_tree* z_tree_new(z_compare_func key_compare_func);

/* Create a new z_tree like z_tree_new and allows to specify functions to
 * free the memory allocated for the key and value that get called when
 * removing the entry from the z_tree.
 * @param key_compare_func
 * @param key_destroy_func
 * @param value_detroy_func
 * @return a new z_tree
 */

z_tree* z_tree_new_full(z_compare_func key_compare_func, z_destroy_notify key_destroy_func,
                        z_destroy_notify value_destroy_func);

/* Destroys the z_tree.If keys and/or values are dynamic allocated, you should
 * either free them first or create the z_tree using z_tree_new_full.
 * In the latter case the destroy functions you supplied will be called on all
 * keys and values before destroying the tree.
 */

void z_tree_destory(z_tree *tree);

/* Inserts a new key and value into a z_tree.
 * If the key already exists in the z_tree its current value is replaced
 * with the new value.
 * @param tree a z_tree
 * @param key a key to insert
 * @param value the value to associate the key.
 */

void z_tree_insert(z_tree *tree, void *key, void *value);

/* Looks up a key in a tree
 * @param tree a z_tree
 * @param key the key to loop up.
 */
void *z_tree_lookup(z_tree *tree, const void *key);

/* Calls the given function for each of the key/value pairs in the
 * z-tree. The function is passed the key and value of each pair,
 * and the given user data parameter.
 */
void z_tree_foreach(z_tree *tree, z_hfunc *func, void *userdata);

/* Returns the number of elements contained in the z_tree
 * @param tree
 * @return the number of key/value pairs
 */
uint32_t z_tree_size(z_tree *tree);

#endif /* _AVLTREE_H_ */
